機密管理サービス AWS Secrets Manager で RDS のパスワードローテーションを試す
こんにちは、菊池です。
先日のAWS Summit 2018 San Francisco では、新しいサービス/機能が多数発表されました。
その中でも、認証情報などの機密情報を管理する AWS Secrets Manager は非常に注目度が高いようです。
この、Secrets Managerを使って、RDSのパスワードを管理・ローテーションを試してみましたので紹介します。
Secrets Manager のRDSパスワードローテーション
前提
実際にやってみてわかったことですが、RDSのパスワード変更はVPC内に起動するLambdaによって実行されます。LambdaがSecret Managerへのパスワード取得・変更と、RDSへの接続・パスワード変更を実行しますので、環境の前提として以下のような条件があります。
- NAT Gatewayを配置し、Lambdaがパブリックリソース(Secret Managerへのエンドポイント)へのアクセスが可能
- RDSでLambdaからの接続を許可するよう、Security Groupを設定
この条件をみたせていないと、ローテーションの処理に失敗します。動作イメージは以下のようになります。
検証の際は、管理対象のRDSの他に、NAT Gatewayなどもあらかじめ作成しておくようにしましょう。
やってみる
それでは実際に試してみます。Secrets Managerのコンソール画面に入りましょう。なんと、サービス開始時点から日本語に対応したコンソールです。
[新しいシークレットの保存]に進みます。シークレットタイプは、[RDSデータベースの認証情報]を選び、対象のユーザ/パスワードを入力します。今回はマスターユーザを使いました。暗号化はデフォルトのまま。
対象のRDSインスタンスを選択して、次へ。
シークレットの名前を設定して、次へ。
自動ローテーションを設定します。[自動ローテーションを有効化]を選択し、間隔を選びます。また、ローテーションを実行するためのシークレットを選択します。これは、ローテーションのためにRDSにログインするための認証情報です。今回は、マスターユーザなので[ステップ1で指定したシークレット]を選択します。別のシークレットも利用できますが、管理対象のRDSでローテーション(パスワード変更)の権限があるユーザのシークレットである必要があります。
最後に、確認して保存します。
ここで、アプリケーションに組み込むためのサンプルコードも取得できます。(後からでも参照できます)
できました。保存時に、初回のローテーションが実行されます。しばらくして問題なければ、下図のように正常に保存された旨が表示されます。
この時、実際の処理としてはCloudFormationでServerlessアプリケーションがデプロイされ、Lambda関数とIAMロールが作成されています。
Lambdaのコンソールをのぞいてみると、Lambda関数が作成・実行されていることがわかります。
パスワードを取得してみる
それでは、AWS CLIを使って、Secrets ManagerからRDSのパスワードを取得、接続してみます。
まずはAWS CLIを最新にして、MySQLクライアントをインストールします。
$ sudo pip install -U awscli $ sudo yum -y install mysql
AWS CLIでsecretsmanager get-secret-value
でシークレットを取得できます。
$ aws secretsmanager get-secret-value \ > --secret-id arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test/testApp/suser-WbKgTG \ > --region ap-northeast-1 { "Name": "test/testApp/suser", "VersionId": "9a47007e-061a-44ff-b3cb-xxxxxxxxxxxx", "SecretString": "{\"username\": \"master\", \"engine\": \"mysql\", \"dbname\": \"test\", \"host\": \"test.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com\", \"password\": \"e2T2Vl3.bNP5g|q]0O1rHo~9kqb4ZEa]\", \"port\": 3306, \"dbInstanceIdentifier\": \"test\"}", "VersionStages": [ "AWSCURRENT", "AWSPENDING" ], "CreatedDate": 1522995744.103, "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test/testApp/suser-WbKgTG" }
SecretStringに、username、dbname、host、passwordなど必要な情報が入っていますので、うまくパースして使うとよいでしょう。パスワードはe2T2Vl3.bNP5g|q]0O1rHo~9kqb4ZEa]
です。
一度コンソールに戻り、ローテーションを実行してみます。
再度、コマンドでシークレットを取得してみます。
$ aws secretsmanager get-secret-value \ > --secret-id arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test/testApp/suser-WbKgTG \ > --region ap-northeast-1 { "Name": "test/testApp/suser", "VersionId": "040e3bca-c234-4db0-a313-xxxxxxxxxxxx", "SecretString": "{\"username\": \"master\", \"engine\": \"mysql\", \"port\": 3306, \"host\": \"test.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com\", \"password\": \"!1)81T~c7>Geh-9xC;8Y&f2Th|ORR+&d\", \"dbname\": \"test\", \"dbInstanceIdentifier\": \"test\"}", "VersionStages": [ "AWSCURRENT", "AWSPENDING" ], "CreatedDate": 1523006698.473, "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test/testApp/suser-WbKgTG" }
パスワードが!1)81T~c7>Geh-9xC;8Y&f2Th|ORR+&d
に変更されていることが確認できます。これでMySQLにログインして、ちゃんと接続できることが確認できました。
まとめ
新しいサービス、AWS Secrets Managerの、シークレットの作成、ローテーションを検証しました。
VPC Lambdaの実行環境で少しハマりましたが、うまく利用することでパスワード管理を楽に運用することができそうです。